/*******************************************************************************
 * Copyright (c) 2011 Benjamin Gmeiner.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Benjamin Gmeiner - Project Owner
 ******************************************************************************/
package com.mediaportal.ampdroid.api.rest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;

public class RestClient {
   public enum RequestMethod {
      GET, POST
   }

   private ArrayList<NameValuePair> params;
   private ArrayList<NameValuePair> headers;
   private String contentBody;

   private String url;

   private int responseCode;
   private String message;

   private String response;

   public String getResponse() {
      return response;
   }

   public String getErrorMessage() {
      return message;
   }

   public int getResponseCode() {
      return responseCode;
   }

   public RestClient(String url) {
      this.url = url;
      params = new ArrayList<NameValuePair>();
      headers = new ArrayList<NameValuePair>();
   }

   public void AddParam(String name, String value) {
      params.add(new BasicNameValuePair(name, value));
   }

   public void AddHeader(String name, String value) {
      headers.add(new BasicNameValuePair(name, value));
   }

   public void Execute(RequestMethod method) throws Exception {
      switch (method) {
      case GET: {
         // add parameters
         String combinedParams = "";
         if (!params.isEmpty()) {
            combinedParams += "?";
            for (NameValuePair p : params) {
               String paramString = p.getName() + "=" + URLEncoder.encode(p.getValue(), "UTF-8");
               if (combinedParams.length() > 1) {
                  combinedParams += "&" + paramString;
               } else {
                  combinedParams += paramString;
               }
            }
         }

         HttpGet request = new HttpGet(url + combinedParams);

         // add headers
         for (NameValuePair h : headers) {
            request.addHeader(h.getName(), h.getValue());
         }

         executeRequest(request, url);
         break;
      }
      case POST: {
         HttpPost request = new HttpPost(url);

         // add headers
         for (NameValuePair h : headers) {
            request.addHeader(h.getName(), h.getValue());
         }
         if (contentBody != null) {
            request.setEntity(new StringEntity(contentBody));
            request.setHeader("Content-Type", "application/x-www-form-urlencoded");
         } else if (!params.isEmpty()) {
            request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
         }

         executeRequest(request, url);
         break;
      }
      }
   }

   private void executeRequest(HttpUriRequest request, String url) {
      HttpClient client = new DefaultHttpClient();
      // client.getParams().s
      HttpResponse httpResponse;
      try {
         httpResponse = client.execute(request);
         responseCode = httpResponse.getStatusLine().getStatusCode();
         message = httpResponse.getStatusLine().getReasonPhrase();

         HttpEntity entity = httpResponse.getEntity();

         if (entity != null) {

            InputStream instream = entity.getContent();
            response = convertStreamToString(instream);

            // Closing the input stream will trigger connection release
            instream.close();
         }

      } catch (ClientProtocolException e) {
         client.getConnectionManager().shutdown();
         e.printStackTrace();
      } catch (IOException e) {
         client.getConnectionManager().shutdown();
         e.printStackTrace();
      }
   }

   private static String convertStreamToString(InputStream is) {

      BufferedReader reader = new BufferedReader(new InputStreamReader(is));
      StringBuilder sb = new StringBuilder();

      String line = null;
      try {
         while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
         }
      } catch (IOException e) {
         e.printStackTrace();
      } finally {
         try {
            is.close();
         } catch (IOException e) {
            e.printStackTrace();
         }
      }
      return sb.toString();
   }

   public void setContentBody(String _body) {
      contentBody = _body;
   }
}
